/*
 * Copyright (c) 2015 Messcat. All rights reserved.
 */
package cc.messcat.web.system;

import java.beans.IntrospectionException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonView;

import cc.messcat.common.constant.CommonConstant;
import cc.messcat.common.model.Pager;
import cc.messcat.common.model.ResponseBean;
import cc.messcat.common.security.token.SecurityHandler;
import cc.messcat.common.util.BeanUtil;
import cc.messcat.common.util.NumberUtil;
import cc.messcat.common.util.StringUtil;
import cc.messcat.entity.area.Area;
import cc.messcat.entity.level.UserLevel;
import cc.messcat.entity.system.McUser;
import cc.messcat.entity.system.McUser.WithoutPasswordView;
import cc.messcat.entity.website.LevelVO;
import cc.messcat.log.OperationLog;
import cc.messcat.service.system.RoleService;
import cc.messcat.service.system.UserLevelService;
import cc.messcat.service.system.UserService;
import cc.messcat.util.HttpClientUtil;
import cc.messcat.util.LevelUtil;
import cc.messcat.util.PropertiesFileReader;
import cc.messcat.util.SmsUtil;

/**
 * 用户功能处理
 *
 * @author Microcat
 * @version 1.0
 */
@RestController
@RequestMapping("/user")
public class UserController {
	private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserLevelService userLevelService;
    
    public static final String SIGNNAME = "魏县扶贫";//阿里云短信签名
    public static final String TEMPLATE_CODE = "SMS_135791626";//阿里云段短信模板
    
    
    @RequestMapping(value = "addUser", method = RequestMethod.POST)
    public Object addUser(McUser user, Long roleId, Long userlevelid) throws Exception {
    	if(roleId == null) {
    		return new ResponseBean(CommonConstant.EXCEPTION_CODE_500, "该用户没有绑定角色");
    	} 
    	if(userlevelid == null) {
    		return new ResponseBean(CommonConstant.EXCEPTION_CODE_500, "该用户没有分配等级");
    	}
        //轻松筹注册
        Map<String, String> response = langkonRegister(user);
        UserLevel userLevel = userLevelService.retrieveObject(userlevelid);
        user.setUserLevel(userLevel);
        user = intoAreaByLevel(user);
        userService.addUser(user, roleId);
        String responeMsg = "手机号已被绑定".equals(response.get("msg")) ? "该手机号被多次绑定" : response.get("msg");
		return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_ADD_SUCCESS+","+ responeMsg);
    }

    //用户管理模糊查询
    @RequestMapping(value = "/finduser", method = RequestMethod.POST)
    @ResponseBody
    public Object finduser(Integer pageNo, Integer pageSize, String username, String realName,
                           String mobilePhone, McUser user, String email, Long countryId, Long villageId,String checkState) throws Exception {
        if (pageNo == null || pageNo < 1) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }

        Subject subject = SecurityUtils.getSubject();
        Object obj = subject.getSession().getAttribute("user");
        McUser loginUser = null;
        if (obj != null) {
            loginUser = (McUser) obj;
        }


        Pager<?> pager = this.userService.getPage(pageNo, pageSize, username, realName, mobilePhone, email, user, loginUser, countryId, villageId ,checkState);
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, pager);
    }


    @OperationLog(desc="删除用户",module="系统配置")
    @RequestMapping(value = "delUser/{id}", method = RequestMethod.DELETE)
    public Object delUser(@PathVariable Long id) throws Exception {
        userService.removeUser(id);
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_DELETE_SUCCESS);
    }

    @OperationLog(desc="更新用户",module="系统配置")
    @RequestMapping(value = "updateUserInfo", method = RequestMethod.POST)
    public Object updateUserInfo(McUser user, Long roleId, Long userlevelid) throws Exception {
    	if(roleId == null) {
    		return new ResponseBean(CommonConstant.EXCEPTION_CODE_500, "该用户没有绑定角色");
    	}
    	 //轻松筹注册
    	Map<String, String> response = langkonRegister(user);
    	if (userlevelid != null) {
    		UserLevel userLevel = userLevelService.retrieveObject(userlevelid);
    		user.setUserLevel(userLevel);
    	}
    	user = intoAreaByLevel(user);
    	userService.modifyUser(user, roleId);
    	
		return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_SUCCESS+","+response.get("msg"));
    }
    
    @OperationLog(desc="更新用户",module="系统配置")
    @RequestMapping(value = "updateUserSafe", method = RequestMethod.POST)
    public Object updateUserSafe(McUser user, @RequestParam String authPassword, @RequestParam String oldPassword,HttpSession session) throws Exception {
        int status = userService.modifyPasswordUser(user, authPassword, oldPassword,session);
        if (status == 0) {
            return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.MSG_UPDATE_PASSWORD_OLD_ERROR);
        }
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_UPDATE_PASSWORD_SUCCESS);
    }

    @RequestMapping(value = "getUser/{id}", method = RequestMethod.GET)
    @JsonView(WithoutPasswordView.class)
    public Object getUser(@PathVariable Long id) throws Exception {
        McUser user = userService.retrieveUserById(id);
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, user);
    }

    @RequestMapping(value = "editUser/{id}", method = RequestMethod.GET)
    @JsonFilter(value = "McFilter")
    public Object editUser(@PathVariable Long id, Integer pageNo, Integer pageSize) throws Exception {
        McUser user = userService.retrieveUserByIdWithoutPermission(id);
        Pager page = roleService.retrieveRoleAll(pageNo, pageSize);
        java.util.Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("user", user);
        resultMap.put("role", page);
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, resultMap);
    }
    
    /**
     * 用户名校验
     * @param username
     * @return
     */
    @RequestMapping(value = "verifyUsername")
    public Object verifyUsername(@RequestParam(name="username",required=true)String username) {
    	List<McUser> list = userService.verifyUsername(username);
    	boolean haveUser = list != null && !list.isEmpty() ? true : false;
    	return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, haveUser);
    }

    @RequestMapping(value = "getUserAll", method = RequestMethod.GET)
    public Object getUserAll(Integer pageNo, Integer pageSize, HttpSession session) throws Exception {
        McUser user = (McUser) session.getAttribute("user");
        Long areaId = user.getAreaId();
        UserLevel userLevel = user.getUserLevel();
        if (NumberUtil.isLongZero(areaId) && NumberUtil.isIntegerZero(userLevel.getLevel())) {
            Pager<McUser> pager = userService.retrieveUserAll(pageNo, pageSize);
            return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, pager);
        } else {
            List<McUser> users = new ArrayList<>();
            int level = userLevel.getLevel();
            while (level < 5) {
                List<Area> areas3 = (List<Area>) session.getAttribute("area" + level);
                for (Area a : areas3) {
                    users.addAll(userService.listByUserArea(a));
                }
                level++;
            }
            Pager<McUser> pager = userService.getPager(pageNo, pageSize, users, null);
            return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_FIND_SUCCESS, pager);
        }
    }

    //修改用户密码
    @OperationLog(desc="修改用户密码",module="系统配置")
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    @ResponseBody
    public Object updatePassword(Long id) {
        if (id != null) {
            McUser user = userService.retrieveObject(id);
            if (user != null) {
                user.setPassword(SecurityHandler.encodePassword("123456", user.getUsername()));
                userService.modifyObject(user);
                return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_UPDATE_SUCCESS, null);
            }
        }
        return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.MSG_UPDATE_FAIL, null);
    }

    private McUser intoAreaByLevel(McUser user) throws InvocationTargetException, IntrospectionException, InstantiationException, IllegalAccessException {
        UserLevel userLevel = user.getUserLevel();
        if (!BeanUtil.isValid(userLevel) || !BeanUtil.isValid(user.getAreaId())) {
            user.setArea(null);
            return user;
        }
        List<LevelVO> list = new ArrayList<>();
        Long areaId = user.getAreaId();
        Area area = userService.retrieveObject(Area.class, areaId);
        user.setArea(area);
        Map<String, Object> map = new HashMap<>();
        for (Integer level = userLevel.getLevel(); level > 0; level--) {
            area = userService.retrieveObject(Area.class, areaId);
            createMap(map, level, area);
            areaId = area.getFatherId();
        }
        LevelUtil.convertMap(user, map);
        return user;
    }

    private Map<String, Object> createMap(Map<String, Object> map, Integer level, Area area) {
        map.put(LevelUtil.Level.getLevelName(level), area.getArea());
        map.put(LevelUtil.Level.getLevelIdName(level), area.getId());
        return map;
    }

    /**
     * 轻松筹注册
     */
	@SuppressWarnings("unchecked")
	private Map<String,String> langkonRegister(McUser user) {
		String response = HttpClientUtil.getInstance().sendHttpPost("http://mpv.langkon.com/api/api.php",
        		"do=reg&account="+user.getMobilePhone()+"&password="+user.getPassword());
		return JSON.parseObject(response, Map.class);
	}
	
	/**
	 * 发送验证码
	 * @throws Exception 
	 */
	@RequestMapping(value = "/smsCode", method = RequestMethod.GET)
	@ResponseBody
	public Object sendCode(@RequestParam(name="phoneNum",required=true)String phoneNum,HttpSession session) throws Exception{
		//查找是否存在对应手机号的用户
		McUser user = userService.retrieveUserByUsername(phoneNum.trim());
		if(user != null){
			 return new ResponseBean("401", CommonConstant.SMS_REGISTERED, "该手机号已注册");
		}
		//随机验证码
		int code = RandomUtils.nextInt(999999);
		if(code<100000){
			code +=100000;
		}
//		String signName = PropertiesFileReader.get("aliyun.signName", "/app.properties");
//    	signName = new String(signName.getBytes("iso-8859-1"));
//    	String templateCode = PropertiesFileReader.get("aliyun.templateCode", "/app.properties");
    	//发送验证码
    	SendSmsResponse response =SmsUtil.sendSms(phoneNum, SIGNNAME, TEMPLATE_CODE, code+"");
    	
    	logger.info("短信接口返回的数据----------------");
    	logger.info("Code=" + response.getCode());
    	logger.info("Message=" + response.getMessage());
    	logger.info("RequestId=" + response.getRequestId());
    	logger.info("BizId=" + response.getBizId());
    	//发送成功
    	if("OK".equalsIgnoreCase(response.getCode())){
    		//保存code到session
    		session.setAttribute(phoneNum.trim(), code+"");
    		return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.SMS_SUCCESS, "发送成功");
    	}else{
    		return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.SMS_FAIL, "发送失败");
    	}
	}
	/**
	 * 校验验证码
	 * @param phoneNum  手机号
	 * @param code 		验证码
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/checkCode", method = RequestMethod.GET)
	@ResponseBody
	public Object checkCode(@RequestParam(name="phoneNum",required=true)String phoneNum,
			@RequestParam(name="code",required=true)String code,HttpSession session){
		
		String localCode = (String) session.getAttribute(phoneNum.trim());
		if(StringUtil.isNotBlank(localCode)){
			if(localCode.equals(code)){
				session.removeAttribute(phoneNum.trim());
				return new ResponseBean(CommonConstant.SUCCESS_CODE_200, CommonConstant.MSG_SUCCESS, "验证码正确");
			}
		}
		return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.MSG_FAIL, "验证码不正确");
	}
	
	/**
	 * 注册手机号码(包括校验验证码)
	 * @param phoneNum  手机号
	 * @param password  密码
	 * @param type      用户类型：贫困户   ，帮扶人员
	 * @return
	 */
	@RequestMapping(value = "/registerPhone", method = RequestMethod.POST)
	@ResponseBody
	public Object registerPhone(@RequestParam(name="phoneNum",required=true)String phoneNum,
			@RequestParam(name="password",required=true)String password,
			@RequestParam(name="type",required=true)String type,
			@RequestParam(name="code",required=true)String code,HttpSession session) throws Exception{
		String localCode = (String) session.getAttribute(phoneNum.trim());
		if(StringUtil.isNotBlank(localCode)){
			if(localCode.equals(code)){
				session.removeAttribute(phoneNum.trim());
			}else{
				return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.SMS_ERROR_CODE, "验证码不正确");
			}
		}else{
			return new ResponseBean(CommonConstant.FAIL_CODE_400, CommonConstant.SMS_ERROR_CODE, "验证码不正确");
		}
		
		McUser user = new McUser();
		user.setUsername(phoneNum);
		user.setMobilePhone(phoneNum);
		user.setPassword(password);
		user.setType(type);
		user.setCheckState("未审核");
		userService.addUserByPhone(user);
		return new ResponseBean(CommonConstant.SUCCESS_CODE_200,CommonConstant.SMS_REGISTER_SUCCESS, "注册成功");
	}
	
}